package com.itheima.aop;

import lombok.val;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Component
@Order(2)
//控制顺序，数字越小，优先级越高
public class AscepDemo1 {

    //通知类型（@around  @Before  @After  @AfterReturning @AfterThrowing）

/*
* @Around环绕通知1：此主机标注的通知方法在目标方法前 后都被执行
* @Before前置执行2：次注解标注的通知方法在目标方法前被执行
* @After后置通知3：此注解标注的通知方法在目标方法后被执行，无论异常都会执行
* @AfterRetruning4:返回后通知，此注解标注的通知方法在目标方法后被执行，有异常不会执行
* @AfterThrowiing5:异常通知后，此注解标注的通知方法发生异常后执行
*
* */


    //excution注解得作用就是主要用来决定项目中的那些方法加入通知

    @Before("execution(* com.itheima.service.impl.*.*(..))")
    public void Before(){
        System.out.println("1前置通知");
    }
    @AfterReturning("execution(* com.itheima.service.impl.*.*(..))")
    public void AfterReturning(){
        System.out.println("1目标方案正常执行后，后置通知");
    }
    @AfterThrowing("execution(* com.itheima.service.impl.*.*(..))")
    public void AfterThrowing(){
        System.out.println("1目标方法抛出异常后，异常通知");
    }
    @After("execution(* com.itheima.service.impl.*.*(..))")
    public void After(){
        System.out.println("1目标方法不管抛不抛出异常最终都是会通知，最终通知");
    }


/*//目标方法

    //around的就是将目标方法包裹起来----现在就是创建目标对象
   @Around("execution(* com.itheima.service.impl.*.*(..))")
    public Object around(ProceedingJoinPoint pjp ){
       try {
           System.out.println("前置通知");
           //目标方法（调用目标方法）
           Object proceed = pjp.proceed();
           System.out.println("目标方案正常执行后，后置通知");
                return proceed;
       } catch (Throwable e) {
           e.printStackTrace();
           System.out.println("目标方法抛出异常后，异常通知");
       }finally {
           System.out.println("目标方法不管抛不抛出异常最终都是会通知，最终通知");
       }
       return null;
   }*/

}
